package com.example.security;

import com.example.controller.LoginFailController;
import com.example.fliter.VerifyCaptchaFilter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.NoOpPasswordEncoder;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

@Configuration
@EnableWebSecurity
// 启用全局方法权限控制, 保证@PreAuthority, @PostAuthority, @PreFilter, @PostFilter生效
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    UserDetailsService userDetailsService;

    @Autowired
    BCryptPasswordEncoder passwordEncoder;  // 使用BCryptPasswordEncoder加密

    @Override
    protected void configure(AuthenticationManagerBuilder builder) throws Exception {
        builder
                .userDetailsService(userDetailsService)
                .passwordEncoder(passwordEncoder)
        ;
    }

    @Override
    protected void configure(HttpSecurity security) throws Exception {
        // 登录验证
        VerifyCaptchaFilter verifyCaptchaFilter = new VerifyCaptchaFilter();
        LoginFailController loginFailHandler = new LoginFailController();
        verifyCaptchaFilter.setAuthenticationFailureHandler(loginFailHandler);

        security
                .addFilterBefore(verifyCaptchaFilter, UsernamePasswordAuthenticationFilter.class)
                .headers().frameOptions().sameOrigin()  // 允许加载加载Frame页面
                .and()
                .authorizeRequests()
                .antMatchers("/user/login.html", "/user/register.html", "/user/get/verify/code",
                        "/user/send/message/verify/code", "/user/do/register", "/forget-password.html",
                        "/user/change/password", "/system/error.html", "/bootstrap/**", "/css/**", "/images/**",
                        "/jquery/**", "/js/**", "/layer/**", "/layui/**")
                .permitAll()    // 可以无条件访问
                .anyRequest()   // 任意请求
                .authenticated()    //需要登录后访问
                .and()
                .formLogin()    // 开启表单登录功能
                .loginPage("/user/login.html") // 登录的页面
                .loginProcessingUrl("/user/do/login")   // 登录请求
                .defaultSuccessUrl("/")  // 登录成功后跳转的页面
                .usernameParameter("idOrPhone") // 账号请求参数名
                .passwordParameter("password")   // 密码请求参数名
                .and()
                .logout()
                .logoutUrl("/user/do/logout")  // 退出登录请求
                .logoutSuccessUrl("/user/login.html")   // 退出成功前往的地址
                .and()
                .csrf()
                .disable()
        ;
        // 只能在一处登录
        security.sessionManagement().maximumSessions(1).expiredUrl("/user/do/login");
    }
}
